#ifndef _DEFLATE_H_
#define _DEFLATE_H_

///////////////////////////////////////////////////////////////////////////////
// TODO#1: remove all short/int data-types and use char[2]/char[4] instead!! //
// TODO#2: use the same bit alignment as deflate standard! see RFC           //
// TODO#3: LZ77 is unbelievably slow :-/                                     //
// TODO#4: set S,L,MIN_MATCH according to config.h                           //
///////////////////////////////////////////////////////////////////////////////

#include <vector>
using std::vector;

// triplets structure for LZ77 algorithm
struct Triplet
{
    unsigned short i,j;   // i=distance,j=length
    unsigned char a;    // literal
    Triplet(unsigned short off, unsigned short len, unsigned char byte) { i = off; j = len; a = byte; }
};

// LZ77 (Deflate defaults: S = 32K, L = 258, MIN_MATCH = 3)
int LZ77_Encode(const unsigned char *T, unsigned int length, vector<Triplet> &triplets, const int S = 32768, const int L = 258, const int MIN_MATCH = 3);
int LZ77_Decode(const vector<Triplet> &triplets, unsigned char *T);

// bit operations
unsigned char BitStream_BitView(const unsigned char *stream, unsigned int pos);
unsigned int BitStream_Bytes(unsigned int bits);
void BitStream_Add(int write_bits, unsigned short val, unsigned char *stream, unsigned int &pos);
unsigned short byte_swap(unsigned short word);
unsigned short bit_reverse(unsigned short bit_len, unsigned short word);

// static Huffman - literals/lengths
void Huffman_Encode_Symbol(unsigned short symbol, unsigned int &pos, unsigned char *encoded);
void Huffman_Decode_Symbol(const unsigned char *encoded, unsigned int &pos, unsigned short &symbol);

// static Huffman - distances
void Distance_Encode(unsigned short val, unsigned char *encoded, unsigned int &pos);
void Distance_Decode(const unsigned char *encoded, unsigned int &pos, unsigned short &val);

// static Huffman - lengths (extra bits)
void Length_Encode(unsigned short value, unsigned char *encoded, unsigned int &pos);
void Length_Decode(unsigned short lenc, unsigned char *encoded, unsigned int &pos, unsigned short &value);

// static Huffman - END OF BLOCK symbol (code 256)
void Insert_EndOfBlock_Symbol(unsigned int &pos, unsigned char *encoded);

#endif	// _DEFLATE_H_